package com.fastjars.business.shiro;

import com.fastjars.business.shiro.model.UserModel;
import com.fastjars.business.shiro.realms.MobileRealm;
import com.fastjars.business.shiro.session.SessionManager;
import com.fastjars.business.spring.ContextHolder;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.List;

/**
 * TokenContextHolder
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2018/03/22
 * @version 1.0.0
 */
public class TokenHolder {
    /**
     * 用户登录管理
     */
    protected static final MobileRealm BASE_REALM = ContextHolder.getBean(MobileRealm.class);
    /**
     * 自定义session管理
     */
    protected static final SessionManager sessionManager = ContextHolder.getBean(SessionManager.class);
    /**
     * 判断是否登录
     * @return
     */
    public static boolean isLogin() {
        return null != SecurityUtils.getSubject().getPrincipal();
    }

    /**
     * 退出登录
     */
    public static void logout() {
        if(isLogin())
            SecurityUtils.getSubject().logout();
    }

    /**
     * 获取Token
     * @return
     */
    public static UserModel getToken(){
        Object principal = SecurityUtils.getSubject().getPrincipal();
        if(null == principal || "".equals(principal.toString().trim()) || "null".equals(principal.toString().trim())){
            return null;
        }
        return (UserModel)principal;
    }

    /**
     * 获取当前用户的Session
     * @return
     */
    public static Session getSession(){
        return SecurityUtils.getSubject().getSession();
    }

    /**
     * 获取当前用户手机
     * @return
     */
    public static String getMobile(){
        return getToken()==null?null:getToken().getMobile();
    }

    /**
     * 获取当前用户账号
     * @return
     */
    public static String getUsername(){
        return getToken()==null?null:getToken().getUsername();
    }

    /**
     * 获取当前用户ID
     * @return
     */
    public static Long getUserId(){
        return getToken()==null?null:getToken().getId();
    }

    /**
     * 把值放入到当前登录用户的Session里
     * @param key
     * @param value
     */
    public static void setVal2Session(Object key ,Object value){
        getSession().setAttribute(key, value);
    }

    /**
     * 从当前登录用户的Session里取值
     * @param key
     * @return
     */
    public static Object getVal2Session(Object key){
        return getSession().getAttribute(key);
    }

    /**
     * 清空当前用户权限信息。
     * 目的：为了在判断权限的时候，再次会再次 <code>doGetAuthorizationInfo(...)  </code>方法。
     * ps：	当然你可以手动调用  <code> doGetAuthorizationInfo(...)  </code>方法。
     * 		这里只是说明下这个逻辑，当你清空了权限，<code> doGetAuthorizationInfo(...)  </code>就会被再次调用。
     */
    public static void clearNowUserAuth(){
        /**
         * 这里需要获取到shrio.xml 配置文件中，对Realm的实例化对象。才能调用到 Realm 父类的方法。
         */
        /**
         * 获取当前系统的Realm的实例化对象，方法一（通过 @link org.apache.shiro.web.mgt.DefaultWebSecurityManager 或者它的实现子类的{Collection<Realm> getRealms()}方法获取）。
         * 获取到的时候是一个集合。Collection<Realm>
         RealmSecurityManager securityManager =
         (RealmSecurityManager) SecurityUtils.getSecurityManager();
         SampleRealm realm = (SampleRealm)securityManager.getRealms().iterator().next();
         */
        /**
         * 方法二、通过ApplicationContext 从Spring容器里获取实列化对象。
         */
        BASE_REALM.clearCachedAuthorizationInfo();
        /**
         * 当然还有很多直接或者间接的方法，此处不纠结。
         */
    }
    /**
     * 根据UserIds清空权限信息。
     * @param userIds	用户ID
     */
    public static void clearUserAuthByUserId(Long...userIds){
        if(null == userIds || userIds.length == 0)	return ;
        List<SimplePrincipalCollection> result = sessionManager.getSimplePrincipalCollectionByUserId(userIds);
        for (SimplePrincipalCollection simplePrincipalCollection : result) {
            BASE_REALM.clearCachedAuthorizationInfo(simplePrincipalCollection);
        }
    }

    /**
     * 根据UserIds清空权限信息
     * 方法重载
     * @param userIds
     */
    public static void clearUserAuthByUserId(List<Long> userIds) {
        if(null == userIds || userIds.size() == 0){
            return ;
        }
        clearUserAuthByUserId(userIds.toArray(new Long[0]));
    }
}
